#include <iostream>
#include <cerrno>
#include <cstring>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

const int size = 1024;

//子进程进行写入
void SubProcessWrite(int wrd)
{
    std::string message = "father,i am your childen process! ";
    while(true)
    {
        sleep(1);
        std::cout<<"childen begin write........."<<std::endl;
        static int cent = 0;
        pid_t id = getpid();
        //拼接消息
        std::string info = message;
        info += "my pid is ";
        info += std::to_string(id);
        info += ", cent: ";
        info += std::to_string(cent);
        //写入
        write(wrd,info.c_str(),info.size());

        cent++;
    }
    std::cout<<"chliden quit ..."<<std::endl;
}

//父进程进行读取
void FatherProcessReader(int rfd)
{
    char inbuffer[size];
    while(true)
    {
        //sleep(1);
        std::cout<<"father begin read,message:"<<std::endl;
        ssize_t n = read(rfd,inbuffer,sizeof(inbuffer) - 1);//读取消息
        if(n > 0)
        {
            inbuffer[n] = 0;//语言限制，在字符串最后加\0
            std::cout<<inbuffer<<std::endl;//打印消息
        }
        else if(n == 0)//读取完毕，或者写端关闭
        {
            std::cout<<"chliden quit,father quit too!"<<std::endl;
        }
        else
        {
            std::cerr<<"read"<<errno<<std::endl;
        }
    }
}

int main()
{
    int pipefd[2];
    int n = pipe(pipefd);//管道创建成功，返回0
    if(n != 0)//管道创建失败
    {
        std::cerr<<"errno "<<errno<<"cerrstring: "<<strerror(errno)<<std::endl;
    }

    std::cout<<"读端->pipefd[0]"<<pipefd[0]<<"写端->pipefd[1]"<<pipefd[1]<<std::endl;
    sleep(1);
    
    pid_t id = fork();//创建子进程
    if(id == 0)
    {
        //子进程进行写入
        std::cout<<"子进程关闭不需要的fd了,准备写消息了"<<std::endl;
        close(pipefd[0]);//关闭读端
        SubProcessWrite(pipefd[1]);//子进程写
        close(pipefd[1]);//任务完成关闭写端
        exit(0);
    }

    //父进程
    std::cout<<"父进程关闭不需要的fd了,准备读消息了"<<std::endl;
    close(pipefd[1]);//关闭写端
    FatherProcessReader(pipefd[0]);//父进程读
    close(pipefd[0]);//任务完成关闭读端

    int status = 0;
    pid_t rid = waitpid(id,&status,0);//父进程等待子进程，并回收
    if(rid > 0)
    {
        std::cout<<"wait child process done , exit sig : "<<(status&0x7f)<<std::endl;
        std::cout<<"wait child process done , exit code(ignore) : "<<((status>>8)&0xFF)<<std::endl;
    }
    return 0;
}